﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Drawing;

using LowLevelGraphics.ImageFormats.SVG;
using LowLevelGraphics.ImageFormats.SVG.Shapes;
using LowLevelGraphics.ImageFormats.SVG.Transformations;

using Rectangle = LowLevelGraphics.ImageFormats.SVG.Shapes.Rectangle;

namespace LowLevelGraphics.ImageFormats
{
    /// <summary>
    /// SVG Reader, use this to read an svg element
    /// </summary>
    public class SVGReader : AbstractImageFormat
    {
        protected static List<Element> m_aElement = new List<Element>();

        /// <summary>
        /// Creates the specified _s file name.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <returns></returns>
        public static UnsafeBitmap Create(string _sFileName)
        {
            m_aElement.Clear();

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.XmlResolver = null;
            xmlDocument.Load(_sFileName);
            XmlNamespaceManager xmlNameSpaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
            xmlNameSpaceManager.AddNamespace("def", "http://www.w3.org/2000/svg");
            //xmlNameSpaceManager.AddNamespace("def", "");

            Dictionary<string, Type> aType = InitializeTypeDictionary();

            CreateSVG(xmlDocument, aType);

            Bitmap bitmap = new Bitmap(1024, 768);
            DrawToBitmap(bitmap);

            return new UnsafeBitmap(bitmap);
        }

        /// <summary>
        /// Creates the SVG.
        /// </summary>
        /// <param name="xmlDocument">The XML document.</param>
        /// <param name="aType">A type.</param>
        private static void CreateSVG(XmlDocument xmlDocument, Dictionary<string, Type> aType)
        {
            foreach (XmlNode xmlNode in xmlDocument.SelectNodes("//*"))
            {
                string sKey = xmlNode.Name;
                if (aType.ContainsKey(sKey))
                {
                    Type type = aType[sKey];
                    Element element = TypeFactory.Create(type, xmlNode);
                    m_aElement.Add(element);
                    Debug.WriteLine(type.Name);
                }
                else
                {
                    Debug.WriteLine(string.Format("Element {0} skipped", sKey));
                }
            }
        }

        /// <summary>
        /// Initializes the type dictionary.
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, Type> InitializeTypeDictionary()
        {
            Dictionary<string, Type> aType = new Dictionary<string, Type>();
            //aType.Add("matrix", typeof(Matrix));
            aType.Add("path", typeof(Path));
            aType.Add("circle", typeof(Circle));
            aType.Add("line", typeof(Line));
            aType.Add("ellipse", typeof(Ellipse));
            aType.Add("text", typeof(Text));
            aType.Add("polygon", typeof(Polygon));
            aType.Add("polyline", typeof(Polyline));
            aType.Add("linearGradient", typeof(LinearGradient));
            aType.Add("radialGradient", typeof(RadialGradient));
            aType.Add("rect", typeof(Rectangle));
            return aType;
        }

        /// <summary>
        /// Draw this element onto g graphics context
        /// </summary>
        /// <param name="g">Graphics context</param>
        /// <param name="bitmap">bitmap</param>
        public static void Draw(Graphics g, Bitmap bitmap)
        {
            g.FillRectangle(Brushes.White, new RectangleF(0, 0, bitmap.Width, bitmap.Height));
            foreach (Element element in m_aElement)
            {
                Shape shape = element as Shape;
                if (shape != null)
                {
                    shape.Draw(g);
                }
            }
        }

        /// <summary>
        /// Draws to bitmap.
        /// </summary>
        /// <param name="bitmap">The bitmap.</param>
        public static void DrawToBitmap(Bitmap bitmap)
        {
            Graphics g = Graphics.FromImage(bitmap);
            Draw(g, bitmap);
        }

        /// <summary>
        /// returns Extension
        /// </summary>
        public override string Extension
        {
            get { return "svg"; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_sFileName"></param>
        /// <returns></returns>
        public override bool Save(string _sFileName)
        {
            throw new NotImplementedException();
        }
    }
}
